﻿using DongFangGuoKai.WMSPlatform.Core;
using DongFangGuoKai.WMSPlatform.Domain.Model;
using DongFangGuoKai.WMSPlatform.Service.OutboundOrderDetail.DTO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DongFangGuoKai.WMSPlatform.Service.OutboundOrderDetail
{
    public class TOutboundOrderDetailService : ITOutboundOrderDetailService
    {
        private readonly SimpleRepositroy<TShippingOrderDetails> shippingorderdetailrepost;
        private readonly SimpleRepositroy<TShippingLockCells> shippinglockcellrepost;
        private readonly SimpleRepositroy<TInventories> inventoriesrepost;
        private readonly SimpleRepositroy<TCells> cellrepost;
        private readonly SimpleRepositroy<TStackingStorages> stackingStoragesrepost;
        private readonly SimpleRepositroy<TInventoryLogs> inventoryLogsrepost;

        public TOutboundOrderDetailService(SimpleRepositroy<TShippingOrderDetails> shippingorderdetailrepost)
        {
            this.shippingorderdetailrepost = shippingorderdetailrepost;

            shippinglockcellrepost = shippingorderdetailrepost.ChangeRepository<SimpleRepositroy<TShippingLockCells>>();
            inventoriesrepost = shippingorderdetailrepost.ChangeRepository<SimpleRepositroy<TInventories>>();
            cellrepost = shippingorderdetailrepost.ChangeRepository<SimpleRepositroy<TCells>>();
            stackingStoragesrepost = shippingorderdetailrepost.ChangeRepository<SimpleRepositroy<TStackingStorages>>();
            inventoryLogsrepost = shippingorderdetailrepost.ChangeRepository<SimpleRepositroy<TInventoryLogs>>();
        }

        /// <summary>
        /// 获取出库单明细  多个物料版本
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="isNetWork"></param>
        /// <returns></returns>
        public List<TShippingOrderDetailPlusDTOGroup> GetTShippingOrderDetailPlus(int pageIndex, int pageSize, int isNetWork)
        {
            var list = shippingorderdetailrepost.GetList(s => s.Status == 0).OrderByDescending(s => s.CreateDate).Skip((pageIndex - 1) * pageSize).Take(pageSize).GroupBy(s => s.OrderSn);

            List<TShippingOrderDetailPlusDTOGroup> resList = new List<TShippingOrderDetailPlusDTOGroup>();
            foreach (var item in list)
            {
                var key = item.Key;
                var lockCellList = new List<TShippingLockCells>();
                foreach (var value in item)
                {
                    var lockCell = shippinglockcellrepost.GetList(s => s.OrderDetailId == value.Id && s.IsPicking == false).ToList();
                    if (isNetWork == 0)
                    {
                        lockCell = shippinglockcellrepost.GetList(s => s.OrderDetailId == value.Id &&
                        s.IsPicking == false && s.AreaCode == "A04").ToList();
                    }
                    if (lockCell != null && lockCell.Count() > 0)
                    {
                        foreach (var item1 in lockCell)
                        {
                            lockCellList.Add(item1);
                        }
                    }
                }
                if (lockCellList != null && lockCellList.Count() > 0)
                {
                    resList.Add(new TShippingOrderDetailPlusDTOGroup(key, lockCellList));
                }
            }
            return resList;
        }

        /// <summary>
        /// 出库复核 最终确定按钮
        /// </summary>
        /// <param name="OrderDTO"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        public bool ChukuMsg(SubmitOutListDTONoNet OrderDTO, out string errorMsg)
        {
            errorMsg = string.Empty;
            try
            {
                shippingorderdetailrepost.AsTenant().BeginTran();
                // 出库复核 修改出库单为复核 和已完成
                var shippingOrder = shippingorderdetailrepost.GetFirst(s => s.Id == OrderDTO.orderDetId);
                if (shippingOrder != null)
                {
                    shippingOrder.IsOutOrderReview = true;
                    shippingOrder.Status = 4;
                    if (!shippingorderdetailrepost.Update(shippingOrder))
                    {
                        errorMsg = "修改出库单为复核失败";
                        shippingorderdetailrepost.AsTenant().RollbackTran();
                        return false;
                    }
                }
                else
                {
                    shippingorderdetailrepost.AsTenant().RollbackTran();
                    errorMsg = "查询不到的出库单id为" + OrderDTO.orderDetId;
                    return false;
                }

                var lockCell = shippinglockcellrepost.GetFirst(s => s.OrderDetailId == shippingOrder.Id);
                if (lockCell == null)
                {
                    shippingorderdetailrepost.AsTenant().RollbackTran();
                    errorMsg = "仓位锁定表查询失败!";
                    return false;
                }
                var inv = inventoriesrepost.GetFirst(s => s.LocationCode == lockCell.CellCode && s.MaterialCode == lockCell.MaterialCode);
                if (inv == null)
                {
                    shippingorderdetailrepost.AsTenant().RollbackTran();
                    errorMsg = "库存查询失败!";
                    return false;
                }
                if (inv.AvailableQty > lockCell.OutQty)
                {
                    inv.AvailableQty -= lockCell.OutQty;
                    inv.Status = 1;
                    if (!inventoriesrepost.Update(inv))
                    {
                        errorMsg = "修改出库数量失败！";
                        shippingorderdetailrepost.AsTenant().RollbackTran();
                        return false;
                    }
                }
                else if (inv.AvailableQty == lockCell.OutQty)
                {
                    //修改组垛数据为失效
                    var tStackingStorages = stackingStoragesrepost.GetList(s => s.Status == 2 && s.MaterialCode == inv.MaterialCode && s.ExpectedLocation == inv.LocationCode);
                    if (tStackingStorages.Count <= 0)
                    {
                        shippingorderdetailrepost.AsTenant().RollbackTran();
                        errorMsg = "未查询到样品组垛数据";
                        return false;
                    }
                    foreach ( var tStackingStorage in tStackingStorages)
                    {
                        tStackingStorage.Status = 0;
                        if (!stackingStoragesrepost.Update(tStackingStorage))
                        {
                            shippingorderdetailrepost.AsTenant().RollbackTran();
                            errorMsg = "系统错误，托盘解绑失败";
                            return false;
                        }
                    }
                    if (!inventoriesrepost.Delete(inv))
                    {
                        errorMsg = "删除库存记录失败！";
                        shippingorderdetailrepost.AsTenant().RollbackTran();
                        return false;
                    }
                }
                else
                {
                    errorMsg = "出库数量有误,出库数量不能大于库存数量";
                    shippingorderdetailrepost.AsTenant().RollbackTran();
                    return false;
                }
                lockCell.IsPicking = true;
                if (!shippinglockcellrepost.Update(lockCell))
                {
                    shippingorderdetailrepost.AsTenant().RollbackTran();
                    errorMsg = "系统错误，库存更改失败";
                    return false;
                }

                //库存流水添加
                TInventoryLogs inventoryLog = new TInventoryLogs()
                {
                    SourceType = 1,
                    SourceSn = shippingOrder.OrderSn,
                    WarehouseId = shippingOrder.WarehouseId,
                    WarehouseName = shippingOrder.WarehouseName,
                    AreaName = shippingOrder.AreaName,
                    LocationCode = inv.LocationCode,
                    //PalletBarcode = inv.PalletBarcode,
                    MaterialId = inv.MaterialId,
                    MaterialCode = inv.MaterialCode,
                    MaterialName = inv.MaterialName,
                    BatchNo = inv.BatchNo,
                    StartQty = lockCell.InventoryQty,
                    ChangeQty = lockCell.OutQty,
                    EndQty = lockCell.InventoryQty - lockCell.OutQty,
                    CreateDate = DateTime.Now,
                    CreateUser = OrderDTO.createUser,
                    CreateUserId = OrderDTO.createUserld
                };

                if (!inventoryLogsrepost.Insert(inventoryLog))
                {
                    shippingorderdetailrepost.AsTenant().RollbackTran();
                    errorMsg = "系统错误，库存流水添加失败";
                    return false;
                }
                shippingorderdetailrepost.AsTenant().CommitTran();
                return true;
            }
            catch (Exception ex)
            {
                shippingorderdetailrepost.AsTenant().RollbackTran();
                errorMsg = ex.Message;
                return false;
            }
        }

        /// <summary>
        /// 添加出库管理 多个物料版本
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddTShippingOrderDetailPlus(TShippingOrderDetailPlusDTO model, out string msg)
        {
            msg = "添加成功";
            try
            {
                shippingorderdetailrepost.AsTenant().BeginTran();
                var isHave = shippingorderdetailrepost.GetFirst(s => s.OrderSn == model.OrderSn);
                if (isHave != null)
                {
                    msg = "领用单号重复，领用单已存在";
                    return false;
                }
                foreach (var mater in model.shippingOrderDetailPlusLockCellDTOs)
                {
                    var inv = inventoriesrepost.GetFirst(s => s.LocationId == Convert.ToInt32(mater.CellCode) && s.Status == 1 && s.MaterialCode == mater.MaterialCode); //mater.CellCode 是指的仓位id因为上游物资系统传的仓位id 这里字段定义错误了
                    if (inv == null)
                    {
                        msg = "找不到库存记录，或者库存正在出库";
                        shippingorderdetailrepost.AsTenant().RollbackTran();
                        return false;
                    }

                    if (inv.AvailableQty < mater.MaterialNum)
                    {
                        msg = mater.CellCode + "仓位，库存数量不足，数量还剩：" + inv.AvailableQty;
                        shippingorderdetailrepost.AsTenant().RollbackTran();
                        return false;
                    }
                    inv.Status = 4;
                    if (!inventoriesrepost.Update(inv))
                    {
                        msg = "修改库存状态失败！";
                        shippingorderdetailrepost.AsTenant().RollbackTran();
                        return false;
                    }

                    TShippingOrderDetails shippingOrderDetail = new TShippingOrderDetails();
                    shippingOrderDetail.OrderSn = model.OrderSn; //同一个订单号
                    shippingOrderDetail.MaterialId = mater.MaterialId;
                    shippingOrderDetail.MaterialCode = mater.MaterialCode;
                    shippingOrderDetail.MaterialName = mater.MaterialName;
                    shippingOrderDetail.MaterialTypeCode = ""; //规格型号 这里把物料类型代替
                    shippingOrderDetail.WarehouseName = model.WhName; //hn
                    shippingOrderDetail.WarehouseId = model.WhId; //hn
                    //shippingOrderDetail.UnitName = mater;
                    shippingOrderDetail.Qty = mater.MaterialNum;
                    shippingOrderDetail.Status = 0;
                    shippingOrderDetail.DeptName = model.NeedDeptName;
                    shippingOrderDetail.CreateDate = DateTime.Now;
                    shippingOrderDetail.CreateUserName = model.NowUserRealName;
                    shippingOrderDetail.CreateUserId = model.NowUserId;
                    shippingOrderDetail.Id = shippingorderdetailrepost.InsertReturnIdentity(shippingOrderDetail);
                    if (shippingOrderDetail.Id <= 0)
                    {
                        msg = "添加出库单失败！";
                        shippingorderdetailrepost.AsTenant().RollbackTran();
                        return false;
                    }

                    //货位锁定明细
                    TShippingLockCells m = new TShippingLockCells();
                    m.OrderDetailId = shippingOrderDetail.Id;
                    m.InventoryId = inv.Id;
                    m.CellId = inv.LocationId;
                    m.CellCode = inv.LocationCode;
                    m.CellName = inv.LocationName;
                    //m.PalletBarcode = inv.PalletBarcode;不需要托盘
                    m.WhId = inv.WarehouseId;
                    m.CellDepthIndex = 0;
                    //m.StackingStorageId = inv.StackingStorageId;
                    m.OutQty = mater.MaterialNum;
                    m.InventoryQty = inv.AvailableQty;
                    m.MaterialId = inv.MaterialId;
                    m.MaterialName = inv.MaterialName;
                    m.MaterialCode = inv.MaterialCode;
                    m.MaterialKeyId = inv.MaterialKeyId;
                    m.BatchNo = inv.BatchNo;
                    m.CreateDate = DateTime.Now;
                    m.RoutewayId = inv.RoutewayId;
                    m.pickingItemId = mater.PickingItemId;//物资明细id  hn
                    m.IsPicking = false;
                    m.materialNorms = mater.MaterialNorms;//规格信号 hn
                    m.AreaCode = inv.AreaCode; //库区
                    m.AreaName = inv.AreaName;
                    if (!shippinglockcellrepost.Insert(m))
                    {
                        msg = "添加出库单明细失败！";
                        shippingorderdetailrepost.AsTenant().RollbackTran();
                        return false;
                    }
                }

                //无异常提交事务
                shippingorderdetailrepost.AsTenant().CommitTran();
                return true;
            }
            catch (Exception ex)
            {
                //事务回滚
                shippingorderdetailrepost.AsTenant().RollbackTran();
                msg = "添加出库单失败，:" + ex.Message;
                return false;
            }
        }

        /// <summary>
        /// 显示出库表
        /// </summary>
        /// <param name="billType"></param>
        /// <param name="houseid"></param>
        /// <param name="name"></param>
        /// <param name="statusNum"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public List<GetChukuDanDTO> GetAllTShippingOrderDetailPlus(int? billType, int? houseid, string? name, int pageIndex, int pageSize, out int totalCount, int? statusNum)
        {
            var listNoPage = shippingorderdetailrepost.GetList();
            if (billType != null)
                listNoPage = listNoPage.Where(s => s.BillType == billType).ToList();
            if (houseid != null)
                listNoPage = listNoPage.Where(s => s.WarehouseId == houseid).ToList();
            if (name != null)
                listNoPage = listNoPage.Where(s => s.MaterialName == name).ToList();
            var items = listNoPage.OrderByDescending(s => s.CreateDate).GroupBy(s => s.OrderSn);
            var list = items.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            totalCount = items.Count();
            List<GetChukuDanDTO> resList = new List<GetChukuDanDTO>();
            foreach (var item in list)
            {
                var key = item.Key;
                var lockCellList = new List<TShippingLockCells>();
                var shippoutList = new List<TShippingOrderDetails>();
                foreach (var value in item)
                {
                    var lockCell = shippinglockcellrepost.GetList(s => s.OrderDetailId == value.Id);
                    foreach (var item1 in lockCell)
                    {
                        lockCellList.Add(item1);
                    }
                    shippoutList.Add(value);
                }
                resList.Add(new GetChukuDanDTO()
                {
                    Status = GetStatus(shippoutList, out int statusNumGet),
                    StatusNum = statusNumGet,
                    OrderSn = key,
                    CreateTime = shippoutList[0].CreateDate,
                    Sum = shippoutList.Sum(s => s.Qty),
                    CreateUserName = shippoutList[0].CreateUserName,
                    AuditUserName = shippoutList[0].AuditUserName,
                    WarehouseName = shippoutList[0].WarehouseName ?? "",
                    DeptName = shippoutList[0].DeptName,
                    shippingOrders = lockCellList,
                });
            }
            if (statusNum != null)
                resList = resList.Where(s => s.StatusNum == statusNum).ToList();
            return resList;
        }

        private string GetStatus(List<TShippingOrderDetails> shippingGoods, out int statusNum)
        {
            int status = 4;
            statusNum = 4;
            string str = "未知状态";
            foreach (var item in shippingGoods)
            {
                if (item.Status != 4 && item.Status != 8)
                {
                    if (item.Status == 0)
                    {
                        status = 0;
                        statusNum = 0;
                        break;
                    }
                    else if (item.Status == 1)
                    {
                        status = 1;
                        statusNum = 1;
                        break;
                    }
                    else if (item.Status == 2)
                    {
                        status = 2;
                        statusNum = 2;
                        break;
                    }
                    else if (item.Status == 3)
                    {
                        status = 3;
                        statusNum = 3;
                        break;
                    }
                }
            }

            bool statusRes = true;
            foreach (var item in shippingGoods)
            {
                if (item.Status != 8)
                    statusRes = false;
            }
            if (statusRes)
            {
                str = "已回传";
                statusNum = 8;
                return str;
            }

            if (status == 0)
            {
                str = "创建";
                statusNum = 0;
                return str;
            }
            else if (status == 1)
            {
                str = "提交";
                statusNum = 1;
                return str;
            }
            else if (status == 2)
            {
                str = "审核通过";
                statusNum = 2;
                return str;
            }
            else if (status == 3)
            {
                str = "作业中";
                statusNum = 3;
                return str;
            }
            else if (status == 4)
            {
                str = "已完成";
                statusNum = 4;
                return str;
            }
            return str;
        }

        /// <summary>
        /// 查询单个出库单
        /// </summary>
        /// <param name="res"></param>
        /// <returns></returns>
        public GetChukuDanDTOHn? GetOneTShippingOrderDetailPlus(out bool res)
        {
            res = true;
            var listNoPage = shippingorderdetailrepost.GetList();
            var list = listNoPage.OrderByDescending(s => s.CreateDate).GroupBy(s => s.OrderSn);
            List<GetChukuDanDTO> resList = new List<GetChukuDanDTO>();
            foreach (var item in list)
            {
                var key = item.Key;
                var lockCellList = new List<TShippingLockCells>();
                var shippoutList = new List<TShippingOrderDetails>();
                foreach (var value in item)
                {
                    var lockCell = shippinglockcellrepost.GetList(s => s.OrderDetailId == value.Id);
                    foreach (var item1 in lockCell)
                    {
                        lockCellList.Add(item1);
                    }
                    shippoutList.Add(value);
                }
                resList.Add(new GetChukuDanDTO()
                {
                    Status = GetStatus(shippoutList, out int statusNumGet),
                    StatusNum = statusNumGet,
                    OrderSn = key,
                    CreateTime = shippoutList[0].CreateDate,
                    Sum = shippoutList.Sum(s => s.Qty),
                    CreateUserName = shippoutList[0].CreateUserName,
                    AuditUserName = shippoutList[0].AuditUserName,
                    WarehouseName = shippoutList[0].WarehouseName ?? "",
                    WarehouseId = shippoutList[0].WarehouseId.GetValueOrDefault(),
                    CreateUserId = shippoutList[0].CreateUserId.GetValueOrDefault(),
                    DeptName = shippoutList[0].DeptName,
                    shippingOrders = lockCellList,
                });
            }
            var resObj = resList.Where(s => s.StatusNum == 4).FirstOrDefault();
            if (resObj == null)
            {
                res = false;
                return null;
            }

            GetChukuDanDTOHn getChukuDanDTOHn = new GetChukuDanDTOHn();
            getChukuDanDTOHn.storeId = resObj.WarehouseId;
            getChukuDanDTOHn.pickingNumber = resObj.OrderSn;
            getChukuDanDTOHn.userId = 2064;

            List<TShippingLockCellDTOHn> shippingLockCellDTOHnList = new List<TShippingLockCellDTOHn>();
            foreach (var item in resObj.shippingOrders)
            {
                TShippingLockCellDTOHn shippingLockCellDTOHn = new TShippingLockCellDTOHn();
                shippingLockCellDTOHn.count = item.OutQty.GetValueOrDefault();
                shippingLockCellDTOHn.batch = item.BatchNo;
                shippingLockCellDTOHn.relationId = item.pickingItemId;
                shippingLockCellDTOHnList.Add(shippingLockCellDTOHn);
            }
            getChukuDanDTOHn.items = shippingLockCellDTOHnList;
            return getChukuDanDTOHn;
        }

        /// <summary>
        /// 修改出库单为已回传
        /// </summary>
        /// <param name="orderSn"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        public bool UpdOutShippingStatus(string orderSn, out string? errorMsg)
        {
            errorMsg = string.Empty;
            try
            {
                var outShipList = shippingorderdetailrepost.GetList(s => s.OrderSn == orderSn);
                if (outShipList == null || outShipList.Count() <= 0)
                {
                    errorMsg = "找不到出库单";
                    return false;
                }
                foreach (var item in outShipList)
                {
                    item.Status = 8;
                }
                if (!shippingorderdetailrepost.UpdateRange(outShipList))
                {
                    errorMsg = "修改出库单状态失败";
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                errorMsg = "修改出库单状态失败，" + ex.Message;
                return false;
            }

        }
    }
}
